/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.web.approvalformat.core.util;

import com.inspur.edp.lcm.metadata.api.entity.MetadataHeader;
import com.inspur.edp.metadata.rtcustomization.api.entity.DimensionExtendEntity;
import com.inspur.edp.web.approvalformat.api.entity.ApprovalFormat;
import com.inspur.edp.web.approvalformat.api.entity.ApprovalFormatEnum;
import com.inspur.edp.web.approvalformat.api.entity.ApprovalFormatTreeNode;
import com.inspur.edp.web.common.utility.StringUtility;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 审批格式服务
 * @author Xu‘fa Wang
 * @date 2020/5/16 14:27
 */
public class ApprovalFormatTreeUtil {
    /**
     * Level 1.2.3是静止的  返回的map里Level1,2,3是不连续的
     * 返回的map可能情形 [Level1, Level2, Level3]:
     * [1,1,1],[1,1,0],[1,0,1],[1,0,0],[0,0,0],[0,1,1],[0,0,1],[0,1,0]
     * 子树（不包含系统预制表单）层级有3种情况：3层，2层，1层
     * 从底向上构建树
     * @param root 根节点
     * @param levelMap 子树Map
     * @Return
     *      *          {
     *      *                 data: {
     *      *                     tplName: '采购订单系统预置模板',
     *      *                     tplType: '系统预制',
     *      *                     billCategory: '',
     *      *                     orgName: '',
     *      *                     operator: 'System',
     *      *                     optTime: '2019.07.10'
     *      *                 },
     *      *                 children: [
     *      *                     {
     *      *                         data: {
     *      *                             tplName: '设备采购订单公共模板',
     *      *                             tplType: '公共模板',
     *      *                             billCategory: '设备采购订单',
     *      *                             orgName: '',
     *      *                             operator: '周小洁',
     *      *                             optTime: '2019.08.10'
     *      *                         },
     *      *                         children: [
     *      *                             {
     *      *                                 data: {
     *      *                                     tplName: '浪潮软件设备采购订单模板',
     *      *                                     tplType: '项目新增',
     *      *                                     billCategory: '设备采购订单',
     *      *                                     orgName: '浪潮软件',
     *      *                                     operator: '周小洁',
     *      *                                     optTime: '2019.09.10'
     *      *                                 },
     *      *                                 children: []
     *      *                             }
     *      *                         ]
     *      *                     }
     *      *                 ]
     *      *             }
     * */
    public static ApprovalFormatTreeNode assembleTree(ApprovalFormat root, Map<String, List<ApprovalFormatTreeNode>> levelMap) {
        ApprovalFormatTreeNode rtcTplTreeRoot = new ApprovalFormatTreeNode(root, new ArrayList<>());
        List<ApprovalFormatTreeNode> level1List = levelMap.get(ApprovalFormatEnum.LEVEL.ONE.name());
        List<ApprovalFormatTreeNode> level2List = levelMap.get(ApprovalFormatEnum.LEVEL.TWO.name());
        List<ApprovalFormatTreeNode> level3List = levelMap.get(ApprovalFormatEnum.LEVEL.THREE.name());
        switch (getDepth(levelMap)){
            case 1:
                rtcTplTreeRoot = handleChildTreeWithDepthOne(rtcTplTreeRoot, level1List, level2List, level3List);
                break;
            case 2:
                rtcTplTreeRoot = handleChildTreeWithDepthTwo(rtcTplTreeRoot, level1List, level2List, level3List);
                break;
            case 3:
                rtcTplTreeRoot = handleChildTreeWithDepthThree(rtcTplTreeRoot, level1List, level2List, level3List);
                break;
            default:
                break;
        }
        return rtcTplTreeRoot;
    }

    public static ApprovalFormat convertToApprovalFormat(MetadataHeader mdInfo, ApprovalFormat approvalFormatFromDatabase, String firstDimension, String secondDimension, boolean isSys) {
        ApprovalFormat approvalFormat = new ApprovalFormat();

        if(approvalFormatFromDatabase != null) {
            approvalFormat.setId(approvalFormatFromDatabase.getId());

            approvalFormat.setAttributeName(approvalFormatFromDatabase.getAttributeName());
            approvalFormat.setFirstDimension(approvalFormatFromDatabase.getFirstDimension());
            approvalFormat.setSecondDimension(approvalFormatFromDatabase.getSecondDimension());
            approvalFormat.setBillCategoryId(approvalFormatFromDatabase.getBillCategoryId());
            approvalFormat.setBizEntityId(approvalFormatFromDatabase.getBizEntityId());
            approvalFormat.setViewObjectId(approvalFormatFromDatabase.getViewObjectId());
            approvalFormat.setApprovalFormId(approvalFormatFromDatabase.getApprovalFormId());
            approvalFormat.setApprovalFormPublishUri(approvalFormatFromDatabase.getApprovalFormPublishUri());
        } else {
            approvalFormat.setId(mdInfo.getId());

            //""可以作为map的key
            approvalFormat.setFirstDimension(StringUtility.isNullOrEmpty(firstDimension) ? "" : firstDimension);
            approvalFormat.setSecondDimension(StringUtility.isNullOrEmpty(secondDimension) ? "" : secondDimension);
        }

        approvalFormat.setCode(mdInfo.getCode());
        approvalFormat.setName(mdInfo.getName());
        approvalFormat.setAttributeName(isSys ? ApprovalFormatEnum.TEMPLATE_ATTRIBUTES.SYS.name() : ApprovalFormatEnum.TEMPLATE_ATTRIBUTES.NEW.name());

        return approvalFormat;
    }

    /**
     * Level 1: 两维度都为空
     * Level 2: 1st维度不空，2nd维度空
     * Level 3: 两维度都不空
     * */
    public static Map<String, List<ApprovalFormatTreeNode>> groupByDimensions(List<ApprovalFormat> children) {
        Map<String, List<ApprovalFormatTreeNode>> levelMap = new HashMap<>();
        if(children == null || children.size() <= 0) {
            return levelMap;
        }
       // 遍历children，处理纬度值为null的场景（如""在oracle数据库返回为null）
       for (ApprovalFormat child: children) {
           if(child.getFirstDimension() == null) {
               child.setFirstDimension("");
           }

           if(child.getSecondDimension() == null) {
               child.setSecondDimension("");
           }
       }

        Map<String, List<ApprovalFormat>> firstDimensionMap = children.stream().collect(Collectors.groupingBy(ApprovalFormat::getFirstDimension));

        Map<String, List<ApprovalFormat>> secondDimensionMap;
        List<ApprovalFormat> level1List, level2List, level3List;
        level1List = new ArrayList<>();
        level2List = new ArrayList<>();
        level3List = new ArrayList<>();
        for(Map.Entry<String, List<ApprovalFormat>> entry : firstDimensionMap.entrySet()) {
            if("".equals(entry.getKey())) {
                //99%只有一个节点，不排除有多个。当有多个时，默认第一个为构造下级树结构的根节点
                //业务上规则，维度1为空的，维度2必定空
                level1List.addAll(entry.getValue());
            } else {
                secondDimensionMap = entry.getValue().stream().collect(Collectors.groupingBy(ApprovalFormat::getSecondDimension));
                for(Map.Entry<String, List<ApprovalFormat>> innerEntry : secondDimensionMap.entrySet()){
                    // 维度1 不空，维度2 空
                    if("".equals(innerEntry.getKey())) {
                        level2List.addAll(innerEntry.getValue());
                    }else{
                        level3List.addAll(innerEntry.getValue());
                    }
                }
            }
            levelMap.put(ApprovalFormatEnum.LEVEL.ONE.name(), level1List.stream().map(item -> new ApprovalFormatTreeNode(item, new ArrayList<>())).collect(Collectors.toList()));
            levelMap.put(ApprovalFormatEnum.LEVEL.TWO.name(), level2List.stream().map(item -> new ApprovalFormatTreeNode(item, new ArrayList<>())).collect(Collectors.toList()));
            levelMap.put(ApprovalFormatEnum.LEVEL.THREE.name(), level3List.stream().map(item -> new ApprovalFormatTreeNode(item, new ArrayList<>())).collect(Collectors.toList()));
        }
        return levelMap;
    }

    public static List<ApprovalFormat> convertToRtcTemplateList(List<DimensionExtendEntity> list, HashMap<String, ApprovalFormat>  formIdApprovalFormatMap) {
        List<ApprovalFormat> retList = new ArrayList<>();
        list.forEach(item -> {
            MetadataHeader mdInfo = item.getExtendMetadataEntity().getHeader();
            ApprovalFormat approvalFormat = formIdApprovalFormatMap.get(mdInfo.getId());
            retList.add(convertToApprovalFormat(mdInfo, approvalFormat, item.getFirstDimension(), item.getSecondDimension(), false));
        });
        return retList;
    }

    private static int getDepth(Map<String, List<ApprovalFormatTreeNode>> levelMap) {
        int depth = 0;

        if(levelMap.get(ApprovalFormatEnum.LEVEL.ONE.name()).size() > 0){
            depth ++;
        }

        if(levelMap.get(ApprovalFormatEnum.LEVEL.TWO.name()).size() > 0) {
            depth ++;
        }

        if(levelMap.get(ApprovalFormatEnum.LEVEL.THREE.name()).size() > 0) {
            depth ++;
        }

        return depth;
    }

    /**
     * 只有一级子树，直接把子节点接到root
     * */
    private static ApprovalFormatTreeNode handleChildTreeWithDepthOne(ApprovalFormatTreeNode root,
                                                               List<ApprovalFormatTreeNode> level1List,
                                                               List<ApprovalFormatTreeNode> level2List,
                                                               List<ApprovalFormatTreeNode> level3List){
        if(level1List.size() > 0) {
            root.setChildren(level1List);
        }

        if(level2List.size() > 0) {
            root.setChildren(level2List);
        }

        if(level3List.size() > 0) {
            root.setChildren(level3List);
        }

        return root;
    }

    /**
     * 只有两级子树：
     * 当Level1不为空时，直接把Level2 或 Level3 子节点接到Level1[0]节点
     * 当Level1为空时，把level3节点与level2节点有相同维度1的元素归集到当前Level2节点；
     * Level3中维度1信息没有与Level2中任何节点匹配，成为孤儿节点；
     * Level2中没有任何子节点的节点，成为孤儿节点。
     * 重新构造一个数组，包含所有的Level2节点，和Level3的孤儿节点，并把该数组设置为root的子树
     * */
    private static ApprovalFormatTreeNode handleChildTreeWithDepthTwo(ApprovalFormatTreeNode root,
                                                               List<ApprovalFormatTreeNode> level1List,
                                                               List<ApprovalFormatTreeNode> level2List,
                                                               List<ApprovalFormatTreeNode> level3List){
        if(level1List.size() > 0){
            if (level2List.size() > 0) {
                level1List.get(0).setChildren(level2List);
            }

            if(level3List.size() > 0) {
                level1List.get(0).setChildren(level3List);
            }

            root.setChildren(level1List);
        } else {
            root.setChildren(groupLevel2And3(level2List,level3List));
        }
        return root;
    }

    /**
     * 有三级子树：
     * 先把Level2和Level3归集，再把归集后List设置为Level1[0]的子树
     * */
    private static ApprovalFormatTreeNode handleChildTreeWithDepthThree(ApprovalFormatTreeNode root,
                                                                 List<ApprovalFormatTreeNode> level1List,
                                                                 List<ApprovalFormatTreeNode> level2List,
                                                                 List<ApprovalFormatTreeNode> level3List){
        level1List.get(0).setChildren(groupLevel2And3(level2List, level3List));
        root.setChildren(level1List);
        return root;
    }

    private static List<ApprovalFormatTreeNode> groupLevel2And3(List<ApprovalFormatTreeNode> level2List, List<ApprovalFormatTreeNode> level3List) {
        List<ApprovalFormatTreeNode> result = new ArrayList<>();
        List<ApprovalFormatTreeNode> children;
        //拥有Level3子节点的维度一信息
        Map<String, Object> firstDimensionWithChildren = new HashMap<>();
        for(ApprovalFormatTreeNode r : level2List) {
            //把level3中与当前level2节点相同维度1的元素归集到当前节点（children）
            children = level3List.stream().filter(item -> item.getData().getFirstDimension().equals(r.getData().getFirstDimension())).collect(Collectors.toList());
            r.setChildren(children);
            firstDimensionWithChildren.put(r.getData().getFirstDimension(), null);
        }

        //包含全部Level2节点
        result.addAll(level2List);

        //查找Level3孤儿节点
        List<ApprovalFormatTreeNode> orphanList = level3List.stream().filter(item -> !firstDimensionWithChildren.containsKey(item.getData().getFirstDimension())).collect(Collectors.toList());
        result.addAll(orphanList);

        return result;
    }

}
